package study.corejava.extend;



import jcore.basic.Student;

import com.basic.SubStudent;

import com.basic.SubStudent2;

//测试4种访问控制，数据的封装性
//             同类    同包子类和同包其他类          不同包子类          不同包其他类
//public       √            √                √           √
//protected    √            √                √           ×
//默认                         √            √                ×           ×
//private      √            ×                ×           ×

public class TestEncapsulation {
	
	public static void main(String[] args) {
		
		Student[] stus = {
				new Student("kiik",99L,20),
				new Student("thank",88L,18),
				new Student("lusenc",77,17)
				
		};
		
		//父类引用指向子类对象
		Student subStudent1 = new SubStudent("Address1 ");
		Student subStudent2 = new SubStudent2(26);
		
		SubStudent sub = new SubStudent("Address2 ");
		
		
		//父类引用指向子类对象，只能访问父类的成员变量，子类新增的成员不能访问，必须强制类型转换
		System.out.println("父类引用指向子类对象："+((SubStudent)subStudent1).getAddress());
		System.out.println("父类引用指向子类对象："+subStudent1.score);
		
		System.out.println("子类引用指向本身："+sub.address);
		
		//子类继承父类的成员
		System.out.println("子类继承父类的方法："+sub.showMessage());
		System.out.println("子类继承父类的成员变量："+sub.score);
		
		sub.hello();
		sub.hello(2);
		
		//多态
		System.out.println("1==> "+"Age = "+subStudent1.age+"    "+subStudent1.getAge());
		System.out.println("2==> "+"Age = "+subStudent2.getAge());
		
		System.out.println("3==> "+"Age = "+sub.getAge());
		
		//父类引用指向子类对象，父类引用访问的是自己的成员
		System.out.println("------------> "+subStudent1.age);
		System.out.println("------------> "+subStudent2.age);//父类的成员age
		System.out.println("------------> "+sub.age);
		
		//不同包其他类中，Student的protected的成员s_p不可访问，例如当类TestEncapsulation与Student不在同一个包下时
//		System.out.println("------------> "+subStudent2.s_p);//父类的成员s_p
		
		for (int i = 0; i < stus.length; i++) {
			stus[i].total();
		}
		
		System.out.println("Average: "+Student.average());
		
		//score是public的，所以此处可以用对象点属性来访问
		System.out.println("public score: "+stus[0].score);
		
		//age是private的，不可直接用对象点属性来访问，只能通过公有的方法来获取
		//System.out.println("Score: "+stus[0].age);
		System.out.println("private age: "+stus[0].getAge());
		
		
		Student student = new Student();
		
		System.out.println(student.age);
	}
}
